package com.sintatico;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Random;

public class GeradorModel implements Serializable {

	private static final long serialVersionUID = 1L;

	private TabelaAnalise tabela;

	private final Character SOURCE = 'S';
	private final Character EPSILON = 'E';

	public TabelaAnalise getTabela() {
		if (tabela == null) {
			tabela = new TabelaAnalise();
			tabela.fillActions();
		}
		return tabela;
	}

	public void setTabela(TabelaAnalise tabela) {
		this.tabela = tabela;
	}

	public String geraSentenca() {
		Random random = new Random();
		String sentenca = String.valueOf(SOURCE);
		int size, sort;

		while (containsNonTerminal(sentenca)) {
			Character nonTerm = getNextNonTerminal(sentenca);
			size = getTabela().getAnalise().get(nonTerm).keySet().size();
			sort = random.nextInt(size);

			Collection<ArrayList<Character>> values = getTabela().getAnalise().get(nonTerm).values();

			CharSequence seq1 = String.valueOf(nonTerm);
			CharSequence seq2 = getElementAt(values, sort);
			sentenca = sentenca.replace(seq1, seq2);
		}

		return sentenca;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public String getElementAt(Collection<ArrayList<Character>> values, int index) {
		String value = "";
		for (Iterator iterator = values.iterator(); iterator.hasNext();) {
			ArrayList<Character> arrayList = (ArrayList<Character>) iterator.next();
			if (index-- == 0) {
				value = arrayList.toString();
			}
		}
		value = value.replace(EPSILON, ' ');
		value = value.replaceAll("\\W", "");
		return reverseString(value);
	}

	private String reverseString(String value) {
		StringBuilder builder = new StringBuilder(value);
		return builder.reverse().toString();
	}

	private boolean containsNonTerminal(String sentenca) {
		for (int i = 0; i < sentenca.length(); i++) {
			if (getTabela().getAnalise().containsKey(sentenca.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	private Character getNextNonTerminal(String sentenca) {
		Character value = null;
		for (int i = 0; i < sentenca.length(); i++) {
			char letra = sentenca.charAt(i);
			if (getTabela().getAnalise().containsKey(letra)) {
				value = letra;
				break;
			}
		}
		return value;
	}

}
